package com.jfok.server.controller;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.List;
import java.util.zip.Deflater;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.jfok.server.DAO.SystemBaseDAO;
import com.jfok.server.common.CommonFunction;
import com.jfok.server.common.FileUploadBean;
import com.jfok.server.hibernate.addition._Addition;
import com.jfok.server.hibernate.addition._Addition_FileData;
import com.jfok.server.hibernate.addition._Addition_ImagePreview;
import com.jfok.server.hibernate.system._Module;
import com.jfok.server.service.AttachmentService;
import com.jfok.server.service.SystemAndLoginInfoService;
import com.jfok.shared.FileTypeVSMimeType;



@Controller
@RequestMapping("/attachment")
public class AttachmentController {

	@Resource
	private SystemBaseDAO systemBaseDAO;

	@Resource
	private AttachmentService attachmentService;

	@RequestMapping("uploadnew.do")
	public @ResponseBody
	Object uploadnew(FileUploadBean uploaditem, BindingResult bindingResult,
			HttpServletRequest request) throws IOException {
		// 写入记录信息
		_Addition addition = attachmentService.uploadnew(uploaditem, bindingResult, request);
		MultipartFile file = uploaditem.getFile();
		// 如果有文件，再写入文件，及缩略图
		if (file != null && file.getOriginalFilename().length() > 0) {
			attachmentService.uploadnewFile(file, addition.getTf_additionId());
		}
		return "{success : true}";
	}

	
	@RequestMapping("uploadnewattachment.do")
	public @ResponseBody
	Object uploadnewattachment(FileUploadBean uploaditem, BindingResult bindingResult,
			HttpServletRequest request) throws IOException {
		MultipartFile file = uploaditem.getFile();
		// 如果有文件，再写入文件，及缩略图
		if (file != null && file.getOriginalFilename().length() > 0) {
			attachmentService.uploadnewFile(file, uploaditem.getTf_additionId());
		}
		return "{success : true}";
	}

	
	@RequestMapping("/preview.do")
	public void getPreviewImage(String id, HttpServletRequest request, HttpServletResponse response)
			throws IOException {

		_Addition_ImagePreview imagePreview = (_Addition_ImagePreview) systemBaseDAO.findById(
				_Addition_ImagePreview.class, id);
		// System.out.println("下载预览文件：" + imagePreview.getTf_filename());
		if (imagePreview == null || imagePreview.getTf_filename() == null)
			return;
		else if (imagePreview.getTf_imagePreview() != null) {
			response.setContentType("image/png");
			response.setHeader("Cache-Control", "max-age=" + 600);
			try {
				response.addHeader("Content-Length", "" + imagePreview.getTf_imagePreview().length());
			} catch (SQLException e) {
				e.printStackTrace();
			}
			Blob blob = imagePreview.getTf_imagePreview();
			writeBlobToResponse(blob, response);
		} else {
			CommonFunction.downloadFilePreviewIcon(
					request.getSession().getServletContext().getRealPath("images/addition/") + "/",
					imagePreview.getTf_filename(), response);
		}
	}

	
	@RequestMapping("/firstimagepreview.do")
	public void getModuleRecordFirstImagePreview(String moduleId, String id,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		@SuppressWarnings("unchecked")
		List<_Addition> additions = (List<_Addition>) systemBaseDAO.findByPropertyWithOtherCondition(
				_Addition.class, "tf_moduleId", moduleId, "tf_moduleIdvalue=" + id);

		for (_Addition addition : additions) {
			// 是否图片文件
			if (addition.getTf_filesize() != null && addition.getTf_filesize() > 0
					&& addition.getTf_imgheight() != null && addition.getTf_imgheight() > 0) {
				getPreviewImage(addition.getTf_additionId().toString(), request, response);
				return;
			}
		}

	}

	
	@RequestMapping("/firstimage.do")
	public void getModuleRecordFirstImage(String moduleId, String id, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		@SuppressWarnings("unchecked")
		List<_Addition> additions = (List<_Addition>) systemBaseDAO.findByPropertyWithOtherCondition(
				_Addition.class, "tf_moduleId", moduleId, "tf_moduleIdvalue=" + id);

		for (_Addition addition : additions) {
			// 是否图片文件
			if (addition.getTf_filesize() != null && addition.getTf_filesize() > 0
					&& addition.getTf_imgheight() != null && addition.getTf_imgheight() > 0) {
				getAttachment(addition.getTf_additionId().toString(), response);
				return;
			}
		}

	}

	
	@RequestMapping("download.do")
	public void download(String id, HttpServletResponse response) throws IOException {

		_Addition_FileData fileData = (_Addition_FileData) systemBaseDAO.findById(
				_Addition_FileData.class, id);
		if (fileData.getTf_filedata() == null) {
			downloadfilenotfound(response);
			return;
		}
		response.addHeader("Content-Disposition", "attachment" + ";filename="
				+ new String(fileData.getTf_filename().getBytes("gb2312"), "iso8859-1"));
		try {
			response.addHeader("Content-Length", "" + fileData.getTf_filedata().length());
		} catch (SQLException e) {
			e.printStackTrace();
		}
		response.setContentType("application/octet-stream");
		Blob blob = fileData.getTf_filedata();
		writeBlobToResponse(blob, response);

	}

	
	@RequestMapping("downloadall.do")
	public void downloadall(String moduleId, String id, String text, HttpServletResponse response)
			throws IOException {

		_Module module = SystemAndLoginInfoService.getModuleWithId(moduleId);
		@SuppressWarnings("unchecked")
		List<_Addition_FileData> additions = ((List<_Addition_FileData>) systemBaseDAO
				.findByPropertyWithOtherCondition(_Addition_FileData.class, _Addition.MODULEID, moduleId,
						_Addition.MODULEKEYID + "=" + id));
		OutputStream os = new ByteArrayOutputStream();
		InputStream input = null;
		ZipOutputStream zipOut = new ZipOutputStream(os);
		zipOut.setEncoding("GBK");
		zipOut.setLevel(Deflater.BEST_COMPRESSION);
		zipOut.setMethod(ZipOutputStream.DEFLATED);
		zipOut.setComment("这是模块" + module.getTf_title() + "中" + text + "的所有附件的压缩文件");
		for (_Addition_FileData addition : additions) {
			if (addition.getTf_filename() != null && addition.getTf_filedata() != null) {
				try {
					input = addition.getTf_filedata().getBinaryStream();
				} catch (SQLException e) {
					e.printStackTrace();
				}
				ZipEntry zipEntry = new ZipEntry(addition.getTf_filename());
				zipEntry.setComment(addition.getTf_name());
				zipOut.putNextEntry(zipEntry);
				int readed = 0;
				byte[] cash = new byte[2048];
				while ((readed = input.read(cash)) > 0)
					zipOut.write(cash, 0, readed);
				input.close();
			}
		}
		zipOut.close();
		CommonFunction.download(os, module.getTf_title() + "--" + text + "附件" + ".zip", response);
		return;
	}

	
	@RequestMapping("getattachment.do")
	public void getAttachment(String id, HttpServletResponse response) throws IOException {

		// 下载上传的原始文件
		_Addition_FileData fileData = (_Addition_FileData) systemBaseDAO.findById(
				_Addition_FileData.class, id);

		if (fileData.getTf_filedata() == null) {
			inlinefilenotfound(response);
			return;
		}
		response.setHeader("Cache-Control", "max-age=" + 600);
		response.addHeader("Content-Disposition", "inline");

		if (fileData.getTf_pdfdata() == null) {

			try {
				response.addHeader("Content-Length", "" + fileData.getTf_filedata().length());
			} catch (SQLException e) {
				e.printStackTrace();
			}
			String mimetype = FileTypeVSMimeType.getMimeType(fileData.getTf_filename());
			if (mimetype == null)
				response.setContentType("application/octet-stream;charset=gb2312");
			else
				response.setContentType(mimetype + ";charset=gb2312");
			Blob blob = fileData.getTf_filedata();
			writeBlobToResponse(blob, response);
		} else {   // doc xls 的pdf 预览
			try {
				response.addHeader("Content-Length", "" + fileData.getTf_pdfdata().length());
			} catch (SQLException e) {
				e.printStackTrace();
			}
			String mimetype = FileTypeVSMimeType.getMimeType(".pdf");
			if (mimetype == null)
				response.setContentType("application/octet-stream;charset=gb2312");
			else
				response.setContentType(mimetype + ";charset=gb2312");
			Blob blob = fileData.getTf_pdfdata();
			writeBlobToResponse(blob, response);
		}

	}

	public void inlinefilenotfound(HttpServletResponse response) throws IOException {
		byte[] buffer = "下载文件失败:没有找到要预览的文件!".getBytes();
		long l = buffer.length;
		response.reset();
		response.addHeader("Content-Disposition", "inline");
		response.addHeader("Content-Length", "" + l);
		OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
		response.setContentType("text/plain");
		toClient.write(buffer);
		toClient.flush();
		toClient.close();
	}

	public void downloadfilenotfound(HttpServletResponse response) throws IOException {

		byte[] buffer = "下载文件失败:没有找到要下载的文件!".getBytes();
		long l = buffer.length;
		String fn = "下载的文件未找到.txt";
		response.reset();
		response.addHeader("Content-Disposition",
				"attachment;filename=" + new String(fn.getBytes("gb2312"), "iso8859-1"));
		response.addHeader("Content-Length", "" + l);
		OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
		response.setContentType("application/octet-stream");
		toClient.write(buffer);
		toClient.flush();
		toClient.close();
	}

	private void writeBlobToResponse(Blob blob, HttpServletResponse response) throws IOException {
		InputStream br = null;
		try {
			br = blob.getBinaryStream();
		} catch (SQLException e1) {
			e1.printStackTrace();
		}
		OutputStream out = response.getOutputStream();
		try {
			byte[] buffer = new byte[1024 * 10];
			int len = 0;
			while ((len = br.read(buffer)) > 0) {
				out.write(buffer, 0, len);
				out.flush();
			}
		} catch (Exception e) {
		} finally {
			br.close();
			out.close();
		}
	}

}
